/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.generator.baseInfo;

import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.QualifiedName;

import io.iec.edp.caf.generator.utils.ExpressionUtils;

/**
 * @author liu_wei
 */
public class AnnotationTypeGenerateInfo extends TypeGeneratorInfo {

    private List<ElementType> targets;
    private RetentionPolicy retention;

    private AnnotationTypeDeclaration typeResult;

    @Override
    protected Boolean getIsInterface() {
        return false;
    }

    @Override
    public AbstractTypeDeclaration getTypeResult() {
        return typeResult;
    }

    @Override
    public void generate() {
        typeResult = ast.newAnnotationTypeDeclaration();
        typeResult.bodyDeclarations().addAll(bodyDeclarations);

        typeResult.setName(ast.newSimpleName(typeName));

        typeResult.modifiers().add(getTargetAnnotation());
        typeResult.modifiers().add(getRetentionAnnotation());
        if (modifiers != null) {

            for (ModifierKeyword modifier : modifiers) {
                typeResult.modifiers().add(ast.newModifier(modifier));
            }
        }
        if (attributes != null) {
            for (AnnotationInfo attributeInfo : attributes) {
                typeResult.modifiers().add(attributeInfo.getAnnotation(ast));
            }
        }
        typeDeclarationResult = typeResult;
    }

    private Annotation getTargetAnnotation() {
        AnnotationInfo tarInfo = new AnnotationInfo();
        tarInfo.setAnnotationType(AnnotationType.SingleMember);

        TypeInfo typeInfo = new TypeInfo("Target");
        typeInfo.setTypePackageName("java.lang.annotation");
        tarInfo.setTypeInfo(typeInfo);
        ArrayInitializer initializer = ast.newArrayInitializer();
        for (ElementType elementType : targets) {
            QualifiedName qualifiedName = ExpressionUtils.getQualifiedName(ast, "ElementType", elementType.name());
            initializer.expressions().add(qualifiedName);
        }
        tarInfo.setSingleParam(initializer);
        return tarInfo.getAnnotation(ast);
    }

    private Annotation getRetentionAnnotation() {
        AnnotationInfo retenInfo = new AnnotationInfo();
        retenInfo.setAnnotationType(AnnotationType.SingleMember);
        TypeInfo typeInfo = new TypeInfo("Retention");
        typeInfo.setTypePackageName("java.lang.annotation");
        retenInfo.setTypeInfo(typeInfo);
        retenInfo.setSingleParam(ExpressionUtils.getQualifiedName(ast, "RetentionPolicy", retention.name()));
        return retenInfo.getAnnotation(ast);
    }
}
